using Newtonsoft.Json;
using Quartz;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using T.FAS.Runtime.Base.Entity;
using T.FAS.Runtime.ScheduleJob.Engine;
using T.FAS.Runtime.ScheduleJob.Manager;
using T.FAS.Runtime.ScheduleJob.SPI;

namespace T.FAS.Runtime.ScheduleJob.Service
{
    public class ScheduleJobExecuteService
    {
        private static ScheduleJobExecuteService _instance = null;
        private static readonly object lockobj = new object();

        private ScheduleJobExecContext context = null;
        private ScheduleJobExecuteService()
        {
            ResumeAllJobInstance();
        }
        public static ScheduleJobExecuteService GetInstance()
        {
            if (_instance == null)
            {
                lock (lockobj)
                {
                    if (_instance == null)
                        _instance = new ScheduleJobExecuteService();
                }
            }
            return _instance;
        }

        public void Execute()
        {
        }
        public async Task Start(ScheduleJobInstance instance)
        {
            if (instance == null || string.IsNullOrEmpty(instance.ID))
                throw new FasException(ScheduleJobRTPExceptionCode.ScheduleJobRTPNullArgument,CommonStringClassService.ScheduleJobExecuteService_Start);

            if (ScheduleJobInstanceManager.GetInstance().IsExistsInstance(instance.ID))
            {
                await ResumeJobInstance(instance.ID);
            }
            else
            {
                await StartNewJob(instance);
            }
        }
        private async Task StartNewJob(ScheduleJobInstance instance)
        {
            context = ScheduleJobExecuteContextBuilder.Build(instance);

            var store = ScheduleJobWrapper.WrapScheduleJobInstance(context);
            //将计划任务实例持久化到数据库
            ScheduleJobInstanceManager.GetInstance().SaveScheduleJobInstance(store);

            //创建作业
            var jobDetail = new ScheduleJobDetailBuilder().BuildDetail(context);
            //创建触发器
            var trigger = new ScheduleJobTriggerFactory().BuildTrigger(context);
            //添加进度
            await StdSchedulerFacotryRepository.GetInstance().StartJob(jobDetail, trigger);
        }
        public async Task PauseJobInstance(string instanceID)
        {
            var jobKey = GetJobKeyByInstanceID(instanceID);

            await StdSchedulerFacotryRepository.GetInstance().PauseJob(jobKey);

            var noticeData = new ScheduleJobStateNoticeData()
            {
                InstanceID = instanceID,
                JobState = JobExecuteState.Pause,
                Message = "中止任务"
            };

            ScheduleJobInstanceManager.GetInstance().UpdateScheduleJobInstanceState(instanceID, noticeData);
        }
        public async Task ResumeJobInstance(string instanceID)
        {
            var jobKey = GetJobKeyByInstanceID(instanceID);

            await StdSchedulerFacotryRepository.GetInstance().ResumeJob(jobKey);

            var noticeData = new ScheduleJobStateNoticeData()
            {
                InstanceID = instanceID,
                JobState = JobExecuteState.Executing,
                Message = "Resume任务"
            };

            ScheduleJobInstanceManager.GetInstance().UpdateScheduleJobInstanceState(instanceID, noticeData);
        }
        public async Task DeleteJobInstance(string instanceID)
        {
            var jobKey = GetJobKeyByInstanceID(instanceID);

            await StdSchedulerFacotryRepository.GetInstance().DeleteJob(jobKey);

            var noticeData = new ScheduleJobStateNoticeData()
            {
                InstanceID = instanceID,
                JobState = JobExecuteState.Deleted,
                Message = "删除任务",
                EndTime = DateTime.Now,
            };

            ScheduleJobInstanceManager.GetInstance().UpdateScheduleJobInstanceState(instanceID, noticeData);
        }
        public void UpdateJobInstance(ScheduleJobInstance instance)
        {
            var filter = new UserDefineQueryFilter();
            filter.Add("ScheduleJobID",instance.ScheduleJobID);

            //将计划任务实例持久化到数据库
            var stores = ScheduleJobInstanceManager.GetInstance().GetScheduleJobInstances(filter);
            if (stores != null && stores.Count > 0)
            {
                stores.ForEach(store=>
                {
                    var ins = ScheduleJobWrapper.WrapScheduleJobInstanceStore(store);

                    var insContext = ScheduleJobExecuteContextBuilder.Build(ins);
                    //测试代码
                    insContext.ScheduleJobMetaData.ScheduleTrigger.CronExpression = "0/1 * * * * ? ";

                    //创建触发器
                    var trigger = new ScheduleJobTriggerFactory().BuildTrigger(insContext);
                    //添加进度
                    var result = StdSchedulerFacotryRepository.GetInstance().UpdateTrigger(insContext.TriggerKey, trigger);
                });
            }
        }
        public void ResumeAllJobInstance()
        {
            var stores = ScheduleJobInstanceManager.GetInstance().GetAllNeedAutoStartScheduleJobInstances();
            if (stores != null)
            {
                stores.ForEach(s=>  
                {
                    var instance = ScheduleJobWrapper.WrapScheduleJobInstanceStore(s);
                    ResumeJobInstance(instance.ID).GetAwaiter().GetResult();
                });
                
            }
        }
        #region 私有方法
        private JobKey GetJobKeyByInstanceID(string instanceID)
        {
            var store = ScheduleJobInstanceManager.GetInstance().GetScheduleJobInstanceByInstanceID(instanceID);

            var instance = ScheduleJobWrapper.WrapScheduleJobInstanceStore(store);

            var jobKey = ScheduleJobKeyUtil.GetJobKey(instance);

            return jobKey;
        }

        #endregion
    }
}
